]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
network: Summarize sections with too many devices
authorFlorian Müllner <fmuellner@gnome.org>
Fri, 13 May 2016 17:42:04 +0000 (19:42 +0200)
committerFlorian Müllner <fmuellner@gnome.org>
Thu, 10 Nov 2016 13:32:07 +0000 (14:32 +0100)
Any network devices appear as top level items in the system status
menu, so on system with an unusually high number of devices, the
menu can end up exceeding the available screen height. While this
is a corner case, leaving important system actions unreachable is
bad. The system menu does not lend itself to scrolling, so handle
this case instead by summarizing sections ("n connections") where
the number of devices exceeds a threshold.

https://bugzilla.gnome.org/show_bug.cgi?id=773892

js/ui/status/network.js

index a9cc4d1e6500c5ed56659a78c5e5c16d77f5f60f..c3af481a67c3be028a6b7fa0e174948632c88e3b 100644 (file)
@@ -40,6 +40,8 @@ const NMAccessPointSecurity = {
     WPA2_ENT: 6
 };
 
+const MAX_DEVICE_ITEMS = 4;
+
 // small optimization, to avoid using [] all the time
 const NM80211Mode = NetworkManager['80211Mode'];
 const NM80211ApFlags = NetworkManager['80211ApFlags'];
@@ -1562,6 +1564,73 @@ const NMVPNSection = new Lang.Class({
 });
 Signals.addSignalMethods(NMVPNSection.prototype);
 
+const DeviceCategory = new Lang.Class({
+    Name: 'DeviceCategory',
+    Extends: PopupMenu.PopupMenuSection,
+
+    _init: function(category) {
+        this.parent();
+
+        this._category = category;
+
+        this.devices = [];
+
+        this.section = new PopupMenu.PopupMenuSection();
+        this.section.box.connect('actor-added', Lang.bind(this, this._sync));
+        this.section.box.connect('actor-removed', Lang.bind(this, this._sync));
+        this.addMenuItem(this.section);
+
+        this._summaryItem = new PopupMenu.PopupSubMenuMenuItem('', true);
+        this._summaryItem.icon.icon_name = this._getSummaryIcon();
+        this.addMenuItem(this._summaryItem);
+
+        this._summaryItem.menu.addSettingsAction(_('Network Settings'),
+                                                 'gnome-network-panel.desktop');
+        this._summaryItem.actor.hide();
+
+    },
+
+    _sync: function() {
+        let nDevices = this.section.box.get_children().reduce(
+            function(prev, child) {
+                return prev + (child.visible ? 1 : 0);
+            }, 0);
+        this._summaryItem.label.text = this._getSummaryLabel(nDevices);
+        let shouldSummarize = nDevices > MAX_DEVICE_ITEMS;
+        this._summaryItem.actor.visible = shouldSummarize;
+        this.section.actor.visible = !shouldSummarize;
+    },
+
+    _getSummaryIcon: function() {
+        switch(this._category) {
+            case NMConnectionCategory.WIRED:
+                return 'network-wired-symbolic';
+            case NMConnectionCategory.WIRELESS:
+            case NMConnectionCategory.WWAN:
+                return 'network-wireless-symbolic';
+        }
+        return '';
+    },
+
+    _getSummaryLabel: function(nDevices) {
+        switch(this._category) {
+            case NMConnectionCategory.WIRED:
+                return ngettext("%s Wired Connection",
+                                "%s Wired Connections",
+                                nDevices).format(nDevices);
+            case NMConnectionCategory.WIRELESS:
+                return ngettext("%s Wi-Fi Connection",
+                                "%s Wi-Fi Connections",
+                                nDevices).format(nDevices);
+            case NMConnectionCategory.WWAN:
+                return ngettext("%s Modem Connection",
+                                "%s Modem Connections",
+                                nDevices).format(nDevices);
+        }
+        return '';
+    }
+});
+
 const NMApplet = new Lang.Class({
     Name: 'NMApplet',
     Extends: PanelMenu.SystemIndicator,
@@ -1605,15 +1674,6 @@ const NMApplet = new Lang.Class({
         this._tryLateInit();
     },
 
-    _createDeviceCategory: function() {
-        let category = {
-            section: new PopupMenu.PopupMenuSection(),
-            devices: [ ],
-        };
-        this.menu.addMenuItem(category.section);
-        return category;
-    },
-
     _tryLateInit: function() {
         if (!this._client || !this._settings)
             return;
@@ -1630,9 +1690,13 @@ const NMApplet = new Lang.Class({
         this._nmDevices = [];
         this._devices = { };
 
-        this._devices.wired = this._createDeviceCategory();
-        this._devices.wireless = this._createDeviceCategory();
-        this._devices.wwan = this._createDeviceCategory();
+        let categories = [NMConnectionCategory.WIRED,
+                          NMConnectionCategory.WIRELESS,
+                          NMConnectionCategory.WWAN];
+        for (let category of categories) {
+            this._devices[category] = new DeviceCategory(category);
+            this.menu.addMenuItem(this._devices[category]);
+        }
 
         this._vpnSection = new NMVPNSection(this._client);
         this._vpnSection.connect('activation-failed', Lang.bind(this, this._onActivationFailed));